package com.woniu.controller;

import com.woniu.pojo.User;
import com.woniu.service.UserService;
import com.woniu.utils.GsonUtils;
import com.woniu.utils.UserToken;
import com.woniu.core.annotation.SystemControllerLog;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Controller
@SessionAttributes(value = "useinf")
public class LoginController {
    @Resource
    private UserService userService;

    private int newcode;

    public int getNewcode() {
        return newcode;
    }

    public void setNewcode() {
        newcode = (int) (Math.random() * 9999) + 100;  //每次调用生成一次四位数的随机数
    }

    //跳转登录界面
    @RequestMapping({"/","login"})
    public String login() {
        return "login";
    }

    //图形验证码
    @RequestMapping("loginDoo")
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //设置页面不缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 在内存中创建图象
        int width = 60, height = 20;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获取画笔
        Graphics g = image.getGraphics();
        //设定背景色
        g.setColor(new Color(200, 200, 200));
        g.fillRect(0, 0, width, height);
        //取随机产生的验证码(4位数字)
        Random rnd = new Random();
        int randNum = rnd.nextInt(8999) + 1000;
        String randStr = String.valueOf(randNum);
        //将验证码存入session
        request.getSession().setAttribute("randStr", randStr);
        //将验证码显示到图象中
        g.setColor(Color.black);
        g.setFont(new Font("", Font.PLAIN, 20));
        g.drawString(randStr, 10, 17);
        // 随机产生100个干扰点，使图象中的验证码不易被其它程序探测到
        for (int i = 0; i < 100; i++) {
            int x = rnd.nextInt(width);
            int y = rnd.nextInt(height);
            g.drawOval(x, y, 1, 1);
        }
        // 输出图象到页面
        ImageIO.write(image, "JPEG", response.getOutputStream());
    }


    //登录

    @RequestMapping("/loginDo")
    @ResponseBody
    public Map<String, Object> loginDo(@Validated User user, Errors errors, String loginType,String code, HttpSession session) {
        Map<String, Object> map = new HashMap<>();
        String emailCode=(String) session.getAttribute("emailCode");
        Boolean f = false;
        UserToken token=null;
        try {
            List<FieldError> fieldErrors = errors.getFieldErrors();
            if (fieldErrors == null || fieldErrors.size() == 0) {
                //获取权限操作对象，利用这个对象来完成登录操作
                Subject subject = SecurityUtils.getSubject();
                if (code != null && !"".equals(code)) {
//                    f = userService.codeVerification(session, code);
//                    f = code.equals("0000")?true:false;
                    f = userService.codeVerification(session, code);
                }
                //用户是否认证过(是否登陆过),进入if表示没有认证过需要进行认证
                //登出，进入这个请求这个用户一定是要完成登录功能，因此我们先登出一次，否则Shiro会有缓存，不能重新登录
                //注意：这么做
                subject.logout();
                if (!subject.isAuthenticated()) {
                    //创建用户认证时的身份令牌，并设置我们从页面获取到的账号和密码
                    //UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUaccount(), user.getUpwd());
                    if (user.getUaccount()!=null&&!"".equals(user.getUaccount())) {
                        if (!f) {
                            throw new NullPointerException("验证码错误");
                        }
                        map.put("codeErro", true);
                        token = new UserToken(user.getUaccount(), user.getUpwd(), loginType);
                    }else if(user.getEmail()!=null&&!"".equals(user.getEmail())) {
                        if (!emailCode.equals(user.getUpwd())){
                            throw new NullPointerException("验证码错误");
                        }
                        token=new UserToken(user.getEmail(), user.getUpwd(), loginType);
                    }else{
                        int newcode = getNewcode();
                        if (Integer.parseInt(user.getUpwd())!= newcode) {
                            throw new NullPointerException("验证码错误");
                        }
                        token=new UserToken(user.getUphone(), user.getUpwd(), loginType);
                    }
                    try {
                        //调用登录，会自动调用我们Realm对象中的认证方法
                        //如果登陆失败会抛出各种异常
                        subject.login(token);
                        map.put("result", true);
                    } catch (UnknownAccountException e) {
                        map.put("uaccount", user.getUaccount());
                        map.put("upwd", user.getUpwd());
                        map.put("result", false);
                        map.put("errorMessage", "账号不存在");
                    } catch (LockedAccountException e) {
                        map.put("uaccount", user.getUaccount());
                        map.put("upwd", user.getUpwd());
                        map.put("errorMessage", "账号被锁定");
                        map.put("result", false);
                    } catch (IncorrectCredentialsException e) {
                        map.put("uaccount", user.getUaccount());
                        map.put("upwd", user.getUpwd());
                        map.put("result", false);
                        map.put("errorMessage", "密码错误");
                    } catch (AuthenticationException e) {
                        map.put("uaccount", user.getUaccount());
                        map.put("upwd", user.getUpwd());
                        map.put("result", false);
                        map.put("errorMessage", "认证失败");
                    }
                }
            }else{
                map.put("codeErro", false);
                map.put("uaccount", user.getUaccount());
                map.put("upwd", user.getUpwd());
                map.put("result", false);
                map.put("errorMessage", "非法认证");
            }
        }catch (NullPointerException e) {
            map.put("codeErro", false);
            map.put("uaccount", user.getUaccount());
            map.put("upwd", user.getUpwd());
            map.put("result", false);
            map.put("errorMessage", "验证码错误");
        }catch (Exception e) {
            e.printStackTrace();
            map.put("codeErro", false);
            map.put("uaccount", user.getUaccount());
            map.put("upwd", user.getUpwd());
            map.put("result", false);
            map.put("errorMessage", "出现其他问题，请联系管理员");
        }
        return map;
    }


//验证码登录--邮箱验证码
    @RequestMapping("sendEmailMassage")
    @ResponseBody
    public Map<String, Object> sendEmailMassage(String email,HttpSession session) {
        String emailLoginMassage = "";
        Map<String, Object> resultMap = new HashMap<>();
        try {
            //userService.login(uphone, getNewcode());
            // "发送成功";
            emailLoginMassage =userService.EmailLogin(email,session);
            if (emailLoginMassage.equals("验证码发送成功")) {
                resultMap.put("result", true);
                resultMap.put("emailLoginMassage", emailLoginMassage);
            } else {
                resultMap.put("emailLoginMassage", emailLoginMassage);
                resultMap.put("result", false);
            }
        } catch (Exception e) {
            resultMap.put("result", false);
            resultMap.put("emailLoginMassage", "验证码发送失败");
        }
        return resultMap;
    }



    //验证码登录--手机短信验证码
    @RequestMapping("sendMassage")
    @ResponseBody
    public Map<String, Object> sendMassage(String uphone) {
        System.out.println(uphone);
        setNewcode();
        String loginMassage = "";
        Map<String, Object> resultMap = new HashMap<>();
        try {
            //userService.login(uphone, getNewcode());
            // "发送成功";
            loginMassage =userService.login(uphone, getNewcode());
            if (loginMassage.equals("发送成功")) {
                resultMap.put("result", true);
                resultMap.put("loginMassage", loginMassage);
            } else {
                resultMap.put("loginMassage", loginMassage);
                resultMap.put("result", false);
            }
        } catch (Exception e) {
            resultMap.put("result", false);
            resultMap.put("loginMassage","短信发送失败");
        }
        return resultMap;
    }

    //验证码验证+重置密码
    @RequestMapping("forgetPwd")
    @ResponseBody
    public Map<String, Object> forgetPwd(User user){
        Map<String, Object> resultMap = new HashMap<>();
        try{
            //getNewcode()
            int newcode = getNewcode();
            if (Integer.parseInt(user.getUpwd())!= newcode) {
                throw new NullPointerException("验证码错误");
            }
            userService.resertPwd(user.getUphone());
            resultMap.put("massage", "重置成功,已将密码重置为123456");
            resultMap.put("result", true);
        }catch (Exception e){
            resultMap.put("massage", "重置失败");
            resultMap.put("result", false);

        }
        return resultMap;
    }
    //人脸识别
    @RequestMapping("searchface")
    @ResponseBody
    public String searchface(@RequestBody @RequestParam(name = "imagebast64") StringBuffer imagebast64, Model model, HttpServletRequest request) throws IOException {
        Map<String, Object> searchface = userService.searchface(imagebast64);
        Subject subject = SecurityUtils.getSubject();
        if(searchface==null||searchface.get("user_id")==null){
            System.out.println("我进来了");
            String flag="fail";
            String s = GsonUtils.toJson(flag);
            return s;
        }
        String user_id = searchface.get("user_id").toString();
        String score=searchface.get("score").toString().substring(0,2);
        int i = Integer.parseInt(score);
        if(i>80){
            subject.logout();
            if (!subject.isAuthenticated()){
                //创建用户认证时的身份令牌，并设置我们从页面获取到的账号和密码
                UserToken userToken=new UserToken(user_id, "","com.woniu.utils.FaceRealm");
                try {
                    subject.login(userToken);
                } catch (AuthenticationException e) {
                    e.printStackTrace();
                    model.addAttribute("errorMessage", "认证失败");
                    return "login";
                }
            }
            model.addAttribute("userinf",user_id);
            HttpSession session = request.getSession();
            session.setAttribute("userinf",user_id);
            String s = GsonUtils.toJson(searchface);
            System.out.println("存入session");
        }
        String s = GsonUtils.toJson(searchface);
        return s;
    }


    @RequestMapping("jumpGetface")
    public String getface(){
        return "getface.html";
    }
    //

    //internationalization
    //登出
    @RequestMapping("logOut")
    public String logOut() {
        Subject subject = SecurityUtils.getSubject();
        //登出当前账号，清空Shiro当前用户的缓存，否则无法重新登录
        subject.logout();
        return "redirect:login";
    }

    @SystemControllerLog(descrption = "用户登录")
    @RequestMapping("main")
    public String main() {
        return "main";
    }

    @RequestMapping("lunbo")
    public String lunbo() {
        return "lunbo";
    }
}

